﻿using APP.DTO.Const;
using Microsoft.Extensions.Primitives;
using System;

namespace App.API.Security
{
    public class JWTSecurityMiddleware
    {
        private readonly RequestDelegate _next;
        private string _limitIP { get; set; }
        private string _noLimitIP { get; set; }
        public JWTSecurityMiddleware(RequestDelegate next,string limitIP,string noLimitIp)
        {
            this._next = next;
            _limitIP = limitIP;
            _noLimitIP = noLimitIp;
        }
        public async Task Invoke(HttpContext context)
        {
            //if (!MiddlewareMsgDTO.IsStartUp)
            //{
            //    throw new UnauthorizedAccessException("服务未启动,请联系管理员启动服务");
            //}
            #region 在线人数
            if (MiddlewareMsgConst.LineNumberCount == 0)
            {
                MiddlewareMsgConst.LineNumberCount = 0;
                MiddlewareMsgConst.MaxUsersCount = 0;
            }
            #endregion

            #region 黑名单
            string[] ipArray = _limitIP.Split(';');
            string ip = context.Request.HttpContext.Connection.RemoteIpAddress.ToString();
            if (ipArray.Any(x => x == ip))
            {
                throw new UnauthorizedAccessException("请求被禁止");
            }
            #endregion


            string tempPath = context.Request.Path.ToString();
            var tempArray = tempPath.Split('/');
            string lastPath = tempArray[tempArray.Length - 1];
            #region 校验是否包含SecurityMsg
            var tempSecurityList = MiddlewareMsgConst.NoSecurityMethodList;
            string tempSecurityMothed = tempSecurityList.Find(x => x == lastPath);
            string securityMsg = string.Empty;

            if (string.IsNullOrEmpty(tempSecurityMothed))
            {
                //需要校验登录状态
                var securityMsgResult = context.Request.Headers.TryGetValue("SecurityMsg", out StringValues tempStr);
                securityMsg = tempStr;
                if (!securityMsgResult || string.IsNullOrEmpty(securityMsg))
                {
                    throw new UnauthorizedAccessException("不被允许的请求");
                }
            }
            else
            {
                //非登录状态
                await _next(context);
                return;
            }
            #endregion
            #region 校验特殊方法

            #endregion
            #region 校验登录信息
            var result = context.Request.Headers.TryGetValue("Authorization", out StringValues authStr);
            #endregion

            if (!result || string.IsNullOrEmpty(authStr))
            {
                throw new UnauthorizedAccessException("未授权请求!!");
            }
            result = JWTTokenContext.Validate(authStr, payLoad =>
            {
                var success = true;
                //可以添加一些自定义验证
                //验证是否包含audience、sub、issuer
                success = success && payLoad["sub"]?.ToString() == JWTTokenContext.sub;
                if (!success)
                {
                    //留着备用
                    //设置Ruse值,把user信息放在payLoad中，（在获取jwt的时候把当前用户存放在payLoad的ruser键中）
                    //如果用户信息比较多，建议放在缓存中，payLoad中存放缓存的Key值
                    return success;
                }
                success = payLoad["audience"]?.ToString() == JWTTokenContext.audience;
                if (!success)
                {
                    return success;
                }
                success = payLoad["issuer"]?.ToString() == JWTTokenContext.issuer;
                if (!success)
                {
                    return success;
                }
                return success;
            });
            if (!result)
            {
                throw new UnauthorizedAccessException("未授权请求");
            }
            #region 校验是否是客户端过来的请求
           
            #endregion
            #region 校验最大账号数和在线数、客户名称、随机码
        
            #endregion
            //执行下一个中间件
            await _next(context);

        }

    }
}
